/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.nhncorp.neptune.tabletserver.action;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.nhncorp.neptune.client.NTable;
import com.nhncorp.neptune.client.Row;
import com.nhncorp.neptune.common.Constants;
import com.nhncorp.neptune.common.conf.NConfiguration;
import com.nhncorp.neptune.common.exception.TestCaseException;
import com.nhncorp.neptune.tablet.TableSchema;
import com.nhncorp.neptune.tablet.TabletInfo;
import com.nhncorp.neptune.tabletserver.TabletServer;
import com.nhncorp.neptune.tabletserver.action.TabletSplitAction.TabletSplitFinishAction;
import com.nhncorp.pleiades.client.LockService;

public class TabletDropAction extends TabletAction implements TabletDropActionIF {
  public static final Log LOG = LogFactory.getLog(TabletDropAction.class.getName());
  public static final String ACTION_TYPE = "TabletDropAction";
  
  static List<String> checkActions = new ArrayList<String>();
  static {  
    checkActions.add(TabletSplitAction.ACTION_TYPE);
    checkActions.add(TabletSplitFinishAction.ACTION_TYPE);
    checkActions.add(MinorCompactionActionIF.ACTION_TYPE);
    checkActions.add(MajorCompactionAction.ACTION_TYPE);
  }
  
  private TabletInfo tabletInfo;
  private LockService lockService;
  private TabletDropActionIF proxyObject;
  protected TabletServer tabletServer;
  
  public TabletDropAction() {
  }
  
  public void init(TabletServer tabletServer, TabletDropActionIF proxyObject, 
                          LockService lockService, TabletInfo tabletInfo) {
    this.tabletServer = tabletServer;
    this.proxyObject = proxyObject;
    this.lockService = lockService;
    this.tabletInfo = tabletInfo;  
  }
  
  public TabletServer getTabletServer() {
    return tabletServer;
  }
  
  @Override
  public String getActionKey() {
    return getActionType();
  }

  @Override
  public String getActionType() {
    return ACTION_TYPE;
  }

  @Override
  public List<String> getRunCheckActionTypes() {
    return checkActions;
  }

  @Override
  public boolean isThreadMode() {
    return true;
  }

  @Override
  public boolean isWaitingMode() {
    return true;
  }

  public void run() {
    try { 
      proxyObject.removeFromMeta();
      LOG.info("End Drop tablet:" + tabletInfo);
    } catch (TestCaseException e) {
//      try {
//        tabletServer.dropedTablet(tabletInfo, false);
//      } catch (IOException e1) {
//        LOG.error(e1);
//      }
    } catch (Exception e) {
      //FIXME 에러가 발생했을 때 drop을 요청한 client까지 전송할 수 있는 방법 필요
      LOG.fatal("TabletServer shutdowned cause fail to drop:" + tabletInfo, e);
//      try {
//        tabletServer.dropedTablet(tabletInfo, false);
//      } catch (IOException e1) {
//        LOG.error(e1);
//      }
      tabletServer.shutdown();
    }
    try {
      lockService.deleteNode(Constants.UPLOADER + "/" + tabletInfo.getTabletName(), true);
    } catch (IOException e) {
      LOG.error("Can't delete UPLOADER lock," + tabletInfo.getTabletName(), e);
    }
  }
  
  public void removeFromMeta() throws Exception {
    //META 삭제
    //LOG.info("Start removeFromMeta:" + tabletInfo);
//    int retry = 0;
//    while(retry < 10) {
//      try {
//        if(TabletServer.deletFromMetaTable(tabletServer.getConf(), tabletInfo, System.currentTimeMillis())) {
//          break;
//        }
//      } catch (IOException e) {
//        LOG.info("Error removeFromMeta:" + e.getMessage());
//      }
//      retry++;
//      Thread.sleep(5 * 1000);
//    }
//    
//    //META 삭제에 실패한 경우
//    if(retry >= 10) {
//      LOG.fatal("Can't delete META while droping:" + tabletInfo);
//      tabletServer.shutdown();
//    }   
  }

  public String getTestHandlerKey() {
    return tabletServer.getHostName();
  }
  
  public static void main(String[] args) throws IOException {
    DecimalFormat df = new DecimalFormat();
    Row.Key[] rowKeys = new Row.Key[100];
    for(int i = 0; i < 100; i++) {
      rowKeys[i] = new Row.Key(df.format(i));
    }
    
    rowKeys[99] = Row.Key.MAX_KEY;
    
    NConfiguration conf = new NConfiguration(); 
    TableSchema tableSchema = new TableSchema(args[0], "Test", new String[]{"Col1", "Col2"});
    NTable.createTable(conf, tableSchema, rowKeys);
    
    //NTable ntable = NTable.openTable(conf, tableSchema.getTableName());
  }
}
